'''
Created on Oct 5, 2012

@author: Himanshu
'''
import copy
import numpy as np
import heapq as hp

class LOOCV:
    """
    Object to perform LOOCV 
    """
    def __init__(self, gestSet):
        self.gestSet = gestSet      
        
    def experiment(self , classifier , file):
        """
        main method to perform LOOCV experiment. Returns the computed class for each instance in self.trainingSet
        """      
        heapLists = {}
        for key in self.gestSet.keys():
            heapLists[key] = []
            trainingSet = copy.deepcopy(self.gestSet)
            testGest = self.gestSet[key]
            del trainingSet[key]
            classifier.setTraining(trainingSet)
            print "-----------------RUNNING ", testGest.getGestureName() , " ------------------"
            testInstances = testGest.returnworldaNorm()
            for instance in testInstances:
                heap = classifier.classifyRestricted(instance)
                heapLists[key].append(heap)
        print "Getting Results"
        allerr = []
        for k in range(1,100):
            print 'k = ' , k
            file.write('k = ')
            file.write(str(k))
            err = []
            for key in self.gestSet.keys():
                print '-------- ' , key , '----------'
                noInstances = self.gestSet[key].returnaNorm().__len__()
                heapList = copy.deepcopy(heapLists[key])
                sumi = 0
                for j in range(noInstances):
                    totalScore = 0
                    invNorms = 0
                    h = heapList[j]
                    for m in range(0,k):
                        a = hp.heappop(h)
                        totalScore += a[1]/a[0]
                        invNorms += (1/a[0])
                    avgScore = totalScore/invNorms
                    sumi += avgScore
                avg = sumi/noInstances
                file.write(key)
                file.write("\n" + "Estimated Score: ")
                file.write(str(avg))
                file.write("\n" + "Real Score: ")
                file.write(str(self.gestSet[key].returnScore()))
                file.write("\n" + "Difference: ")
                file.write(str(avg - self.gestSet[key].returnScore()))
                err.append(avg - self.gestSet[key].returnScore())
            allerr.append(err)
        return allerr
        
            
#        for i in range(0,self.trainingSet.__len__()):
#            print " ----- Running LOOCV Experiment " , i+1 , " --------"
#            reducedFeatureSet = copy.deepcopy(self.trainingSet)
#            reducedFeatureSet.pop(i)
#            reducedTargetVector = copy.deepcopy(self.targetVector)
#            reducedTargetVector.pop(i)
#            classifier.setTrainingSet(reducedFeatureSet)
#            classifier.setTargetVector(reducedTargetVector)
#            computedClass.append(classifier.classify(self.trainingSet[i]))
#        return computedClass      
            
    def countErrors(self,computedClass):
        diff = np.subtract(self.targetVector - computedClass)
        return np.linalg.norm(diff)
        """errors = 0
        for i in range(0,self.targetVector.__len__()):
            if (self.targetVector[i] != computedClass[i]):
                errors = errors + 1
        return errors"""
            
            
            
            
            
            